package org.esk.dablog.web.elements;

import org.esk.dablog.ApplicationConstants;

import java.util.Calendar;
import java.util.Locale;
import java.util.List;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;

/**
 * This class
 * User: jc
 * Date: 22.11.2006
 * Time: 16:53:09
 * $Id:$
 */
public class CalendarBean {
    private static final String CALENDAR_PREFIX = "<table border='0' class='c__calendar'>";
    private static final String CALENDAR_SUFFIX = "</table>";
    private static final String WEEK_PREFIX = "<tr>";
    private static final String WEEK_SUFFIX = "</tr>";
    private static final String DAY_NAME_PREFIX = "<th>";
    private static final String DAY_NAME_SUFFIX = "</th>";
    private static final String DAY_PREFIX = "<td>";
    private static final String DAY_SUFFIX = "</td>";


    private String calendarPrefix = CALENDAR_PREFIX;
    private String calendarSuffix = CALENDAR_SUFFIX;
    private String weekPrefix = WEEK_PREFIX;
    private String weekSuffix = WEEK_SUFFIX;
    private String dayPrefix = DAY_PREFIX;
    private String daySuffix = DAY_SUFFIX;
    private String dayNamePrefix = DAY_NAME_PREFIX;
    private String dayNameSuffix = DAY_NAME_SUFFIX;

    private static final int[] weekDays = new int[]{Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY, Calendar.THURSDAY,
            Calendar.FRIDAY, Calendar.SATURDAY, Calendar.SUNDAY};



    private Calendar currentDate;
    private Locale locale;
    private List dates;
    private String dayHref;
    private boolean showMonths;

    public String getRendered() {
        return render();
    }

    public String render() {
        String[] weekDayNames = new DateFormatSymbols(getLocale()).getShortWeekdays();
        Calendar c = Calendar.getInstance();
        c.setFirstDayOfWeek(Calendar.MONDAY);
        c.setTime(getCurrentDate().getTime());
        c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));

        StringBuffer sb = new StringBuffer();
        sb.append(getCalendarPrefix());
        if(isShowMonths()) {
          appendMonths(sb, c);
        }
        sb.append(getWeekPrefix());
        for (int i = 0; i < weekDays.length; ++i) {
            sb.append(getDayNamePrefix());
            sb.append(weekDayNames[weekDays[i]]);
            sb.append(getDayNameSuffix());
        }

        sb.append(getWeekSuffix());
        for (int i = 0; i < 5; ++i) {
            sb.append(getWeekPrefix());
            for (int k = 0; k < 7; ++k) {
                c.set(Calendar.MONTH, getCurrentDate().get(Calendar.MONTH));
                c.set(Calendar.DAY_OF_WEEK, weekDays[k]);
                c.set(Calendar.WEEK_OF_MONTH, i + 1);
                sb.append(processDate(c));
            }
            sb.append(getWeekSuffix());
        }
        sb.append(getCalendarSuffix());
        return sb.toString();
    }

    /**
     * function appends months navigation
     * @param sb
     */
    private void appendMonths(StringBuffer sb, Calendar c) {
        String[] months = new DateFormatSymbols(getLocale()).getMonths();
        Calendar prev = (Calendar) c.clone();
        prev.add(Calendar.MONTH, -1);
        Calendar next = (Calendar) c.clone();
        next.add(Calendar.MONTH, 1);

        sb.append("<tr><td colspan='7'>");
        sb.append("<table><tr>");
        sb.append("<td><a href='").append(getDayHref());
        sb.append('/').append(ApplicationConstants.getInstance().getSystemDateFormat().format(prev.getTime()));
        sb.append("'>&lt;</a></td>");
        sb.append("<td>").append(months[c.get(Calendar.MONTH)]).append("</td>");
        sb.append("<td><a href='").append(getDayHref());
        sb.append('/').append(ApplicationConstants.getInstance().getSystemDateFormat().format(next.getTime()));
        sb.append("'>&gt;</a></td>");
        sb.append("</tr></table>");
        sb.append("</td></tr>");
    }

    /**
     * Processes single day in month
     *
     * @param c
     * @return
     */
    private String processDate(Calendar c) {
        int day = c.get(Calendar.DAY_OF_MONTH);
        boolean hasEvents = false;
        boolean currentMonth = c.get(Calendar.MONTH) == getCurrentDate().get(Calendar.MONTH);

        if (currentMonth && dates != null && dates.size() >= day - 1) {
            hasEvents = ((Integer) dates.get(day - 1) > 0);
        }

        String dayPrefix = "";
        String daySuffix = "";

        if (!currentMonth) {
            dayPrefix = "<td class='c__calendar_prev_month'>";
            daySuffix = "</td>";
        } else {
            if (hasEvents) {
                dayPrefix = "<td class='c__calendar_has_events'>";
                daySuffix = "</td>";
            } else {
                dayPrefix = getDayPrefix();
                daySuffix = getDaySuffix();
            }
        }
        dayPrefix += "<a href='" + getDayHref() 
                + "/" + ApplicationConstants.getInstance().getSystemDateFormat().format(c.getTime()) + "'>";
        daySuffix = "</a>" + daySuffix;
        return dayPrefix + day + daySuffix;
    }


    public boolean isShowMonths() {
        return showMonths;
    }

    public void setShowMonths(boolean showMonths) {
        this.showMonths = showMonths;
    }

    public Locale getLocale() {
        return locale != null ? locale : Locale.getDefault();
    }

    public void setLocale(Locale locale) {
        this.locale = locale;
    }

    public String getDayHref() {
        return dayHref;
    }

    public void setDayHref(String dayHref) {
        this.dayHref = dayHref;
    }

    public List getDates() {
        return dates;
    }

    public void setDates(List dates) {
        this.dates = dates;
    }

    public String getDayNamePrefix() {
        return dayNamePrefix;
    }

    public void setDayNamePrefix(String dayNamePrefix) {
        this.dayNamePrefix = dayNamePrefix;
    }

    public String getDayNameSuffix() {
        return dayNameSuffix;
    }

    public void setDayNameSuffix(String dayNameSuffix) {
        this.dayNameSuffix = dayNameSuffix;
    }


    public Calendar getCurrentDate() {
        return currentDate;
    }

    public void setCurrentDate(Calendar currentDate) {
        this.currentDate = currentDate;
    }

    public String getCalendarPrefix() {
        return calendarPrefix;
    }

    public void setCalendarPrefix(String calendarPrefix) {
        this.calendarPrefix = calendarPrefix;
    }

    public String getCalendarSuffix() {
        return calendarSuffix;
    }

    public void setCalendarSuffix(String calendarSuffix) {
        this.calendarSuffix = calendarSuffix;
    }

    public String getWeekPrefix() {
        return weekPrefix;
    }

    public void setWeekPrefix(String weekPrefix) {
        this.weekPrefix = weekPrefix;
    }

    public String getWeekSuffix() {
        return weekSuffix;
    }

    public void setWeekSuffix(String weekSuffix) {
        this.weekSuffix = weekSuffix;
    }

    public String getDayPrefix() {
        return dayPrefix;
    }

    public void setDayPrefix(String dayPrefix) {
        this.dayPrefix = dayPrefix;
    }

    public String getDaySuffix() {
        return daySuffix;
    }

    public void setDaySuffix(String daySuffix) {
        this.daySuffix = daySuffix;
    }
}
